package com.zc.gateway.jwt;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.zc.commons.auth.dto.CurrentAuthUser;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;

/**
 * jwt处理service
 *
 * @author zcj
 * @version 1.0.0
 * @date 2022/1/10 14:32
 */
@Service
@ConfigurationProperties(prefix = "com.zc.gateway.security.jwt")
public class JsonWebJwtService {

    /**
     * 用于signature（签名）部分解密
     */
    @Value("${primaryKey:zcc}")
    private String primaryKey;

    /**
     * 签发者
     */
    @Value("${iss:gatewayServer}")
    private String iss;

    /**
     * 添加角色的key
     */
    @Value("${roleClaims:roles}")
    private String roleClaims;

    /**
     * 添加用户的key
     */
    @Value("${userClaims:user}")
    private String userClaims;

    /**
     * 过期时间是3600秒，既是1个小时
     */
    @Value("${expiration:3600}")
    private Integer expiration;

    /**
     * 选择了记住我之后的过期时间为7天
     */
    @Value("${expirationRemember:604800}")
    private Integer expirationRemember;

    /**
     * 根据用户和角色生成token
     *
     * @param currentAuthUser
     * @param rememberMe
     * @return
     */
    public String generateJwtToken(CurrentAuthUser currentAuthUser, boolean rememberMe) {
        int expiration = rememberMe ? this.expirationRemember : this.expiration;

        HashMap<String, Object> map = new HashMap<>();
        map.put(userClaims, JSON.toJSONString(currentAuthUser, SerializerFeature.WriteMapNullValue));

        String jwtToken = Jwts.builder()
                .signWith(SignatureAlgorithm.HS256, this.primaryKey)
                .setSubject(currentAuthUser.getAccount())
                .setClaims(map)
                .setIssuer(iss)
                .setIssuedAt(new Date())
                .setExpiration(null)
                .compact();
        return jwtToken;
    }

    /**
     * 获取token
     *
     * @param token
     * @return
     */
    public Claims getTokenBody(String str) {
        return Jwts.parser()
                .setSigningKey(this.primaryKey)
                .parseClaimsJws(str)
                .getBody();
    }

    public String getUserClaims() {
        return userClaims;
    }
}
